home *** CD-ROM | disk | FTP | other *** search
- ;;; makeinfo.el --- run makeinfo conveniently
-
- ;; Copyright (C) 1991, 1993 Free Software Foundation, Inc.
-
- ;; Author: Robert J. Chassell
- ;; Maintainer: FSF
-
- ;; This file is part of GNU Emacs.
-
- ;; GNU Emacs is free software; you can redistribute it and/or modify
- ;; it under the terms of the GNU General Public License as published by
- ;; the Free Software Foundation; either version 2, or (at your option)
- ;; any later version.
-
- ;; GNU Emacs is distributed in the hope that it will be useful,
- ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
- ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ;; GNU General Public License for more details.
-
- ;; You should have received a copy of the GNU General Public License
- ;; along with GNU Emacs; see the file COPYING. If not, write to the
- ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- ;; Boston, MA 02111-1307, USA.
-
- ;;; Commentary:
-
- ;;; The Texinfo mode `makeinfo' related commands are:
-
- ;; makeinfo-region to run makeinfo on the current region.
- ;; makeinfo-buffer to run makeinfo on the current buffer, or
- ;; with optional prefix arg, on current region
- ;; kill-compilation to kill currently running makeinfo job
- ;; makeinfo-recenter-makeinfo-buffer to redisplay *compilation* buffer
-
- ;;; Keybindings (defined in `texinfo.el')
-
- ;; makeinfo bindings
- ; (define-key texinfo-mode-map "\C-c\C-m\C-r" 'makeinfo-region)
- ; (define-key texinfo-mode-map "\C-c\C-m\C-b" 'makeinfo-buffer)
- ; (define-key texinfo-mode-map "\C-c\C-m\C-k" 'kill-compilation)
- ; (define-key texinfo-mode-map "\C-c\C-m\C-l"
- ; 'makeinfo-recenter-compilation-buffer)
-
- ;;; Code:
-
- ;;; Variables used by `makeinfo'
-
- (require 'compile)
-
- (defvar makeinfo-run-command "makeinfo"
- "*Command used to run `makeinfo' subjob.
- The name of the file is appended to this string, separated by a space.")
-
- (defvar makeinfo-options "--fill-column=70"
- "*String containing options for running `makeinfo'.
- Do not include `--footnote-style' or `--paragraph-indent';
- the proper way to specify those is with the Texinfo commands
- `@footnotestyle` and `@paragraphindent'.")
-
- (require 'texinfo)
-
- (defvar makeinfo-compilation-process nil
- "Process that runs `makeinfo'. Should start out nil.")
-
- (defvar makeinfo-temp-file nil
- "Temporary file name used for text being sent as input to `makeinfo'.")
-
- (defvar makeinfo-output-file-name nil
- "Info file name used for text output by `makeinfo'.")
-
-
- ;;; The `makeinfo' function definitions
-
- (defun makeinfo-region (region-beginning region-end)
- "Make Info file from region of current Texinfo file, and switch to it.
-
- This command does not offer the `next-error' feature since it would
- apply to a temporary file, not the original; use the `makeinfo-buffer'
- command to gain use of `next-error'."
-
- (interactive "r")
- (let (filename-or-header
- filename-or-header-beginning
- filename-or-header-end)
- ;; Cannot use `let' for makeinfo-temp-file or
- ;; makeinfo-output-file-name since `makeinfo-compilation-sentinel'
- ;; needs them.
-
- (setq makeinfo-temp-file
- (concat
- (make-temp-name
- (substring (buffer-file-name)
- 0
- (or (string-match "\\.tex" (buffer-file-name))
- (length (buffer-file-name)))))
- ".texinfo"))
-
- (save-excursion
- (save-restriction
- (widen)
- (goto-char (point-min))
- (let ((search-end (save-excursion (forward-line 100) (point))))
- ;; Find and record the Info filename,
- ;; or else explain that a filename is needed.
- (if (re-search-forward
- "^@setfilename[ \t]+\\([^ \t\n]+\\)[ \t]*"
- search-end t)
- (setq makeinfo-output-file-name
- (buffer-substring (match-beginning 1) (match-end 1)))
- (error
- "The texinfo file needs a line saying: @setfilename <name>"))
-
- ;; Find header and specify its beginning and end.
- (goto-char (point-min))
- (if (and
- (prog1
- (search-forward tex-start-of-header search-end t)
- (beginning-of-line)
- ;; Mark beginning of header.
- (setq filename-or-header-beginning (point)))
- (prog1
- (search-forward tex-end-of-header nil t)
- (beginning-of-line)
- ;; Mark end of header
- (setq filename-or-header-end (point))))
-
- ;; Insert the header into the temporary file.
- (write-region
- (min filename-or-header-beginning region-beginning)
- filename-or-header-end
- makeinfo-temp-file nil nil)
-
- ;; Else no header; insert @filename line into temporary file.
- (goto-char (point-min))
- (search-forward "@setfilename" search-end t)
- (beginning-of-line)
- (setq filename-or-header-beginning (point))
- (forward-line 1)
- (setq filename-or-header-end (point))
- (write-region
- (min filename-or-header-beginning region-beginning)
- filename-or-header-end
- makeinfo-temp-file nil nil))
-
- ;; Insert the region into the file.
- (write-region
- (max region-beginning filename-or-header-end)
- region-end
- makeinfo-temp-file t nil)
-
- ;; Run the `makeinfo-compile' command in the *compilation* buffer
- (save-excursion
- (makeinfo-compile
- (concat makeinfo-run-command
- " "
- makeinfo-options
- " "
- makeinfo-temp-file)
- "Use `makeinfo-buffer' to gain use of the `next-error' command"
- nil)))))))
-
- ;;; Actually run makeinfo. COMMAND is the command to run.
- ;;; ERROR-MESSAGE is what to say when next-error can't find another error.
- ;;; If PARSE-ERRORS is non-nil, do try to parse error messages.
- (defun makeinfo-compile (command error-message parse-errors)
- (let ((buffer
- (compile-internal command error-message nil
- (and (not parse-errors)
- ;; If we do want to parse errors, pass nil.
- ;; Otherwise, use this function, which won't
- ;; ever find any errors.
- '(lambda (&rest ignore)
- (setq compilation-error-list nil))))))
- (set-process-sentinel (get-buffer-process buffer)
- 'makeinfo-compilation-sentinel)))
-
- ;; Delete makeinfo-temp-file after processing is finished,
- ;; and visit Info file.
- ;; This function is called when the compilation process changes state.
- ;; Based on `compilation-sentinel' in compile.el
- (defun makeinfo-compilation-sentinel (proc msg)
- (compilation-sentinel proc msg)
- (if (and makeinfo-temp-file (file-exists-p makeinfo-temp-file))
- (delete-file makeinfo-temp-file))
- ;; Always use the version on disk.
- (if (get-file-buffer makeinfo-output-file-name)
- (progn (set-buffer makeinfo-output-file-name)
- (revert-buffer t t))
- (find-file makeinfo-output-file-name))
- (goto-char (point-min)))
-
- (defun makeinfo-buffer ()
- "Make Info file from current buffer.
-
- Use the \\[next-error] command to move to the next error
- \(if there are errors\)."
-
- (interactive)
- (cond ((null buffer-file-name)
- (error "Buffer not visiting any file"))
- ((buffer-modified-p)
- (if (y-or-n-p "Buffer modified; do you want to save it? ")
- (save-buffer))))
-
- ;; Find and record the Info filename,
- ;; or else explain that a filename is needed.
- (save-excursion
- (goto-char (point-min))
- (let ((search-end (save-excursion (forward-line 100) (point))))
- (if (re-search-forward
- "^@setfilename[ \t]+\\([^ \t\n]+\\)[ \t]*"
- search-end t)
- (setq makeinfo-output-file-name
- (buffer-substring (match-beginning 1) (match-end 1)))
- (error
- "The texinfo file needs a line saying: @setfilename <name>"))))
-
- (save-excursion
- (makeinfo-compile
- (concat makeinfo-run-command " " makeinfo-options
- " " buffer-file-name)
- "No more errors."
- t)))
-
- (defun makeinfo-recenter-compilation-buffer (linenum)
- "Redisplay `*compilation*' buffer so most recent output can be seen.
- The last line of the buffer is displayed on
- line LINE of the window, or centered if LINE is nil."
- (interactive "P")
- (let ((makeinfo-buffer (get-buffer "*compilation*"))
- (old-buffer (current-buffer)))
- (if (null makeinfo-buffer)
- (message "No *compilation* buffer")
- (pop-to-buffer makeinfo-buffer)
- (bury-buffer makeinfo-buffer)
- (goto-char (point-max))
- (recenter (if linenum
- (prefix-numeric-value linenum)
- (/ (window-height) 2)))
- (pop-to-buffer old-buffer)
- )))
-
- ;;; Place `provide' at end of file.
- (provide 'makeinfo)
-
- ;;; makeinfo.el ends here
-
-